using System;
using System.Text;
using System.Collections.Generic;

using Microsoft.VisualStudio.TestTools.UnitTesting;

using SharpCore.NullableTypes;

namespace ShapreCore.NullableTypes.Testing
{
	/// <summary>
	/// Provides unit tests for the SharpCore.NullableTypes classes.
	/// </summary>
	[TestClass]
	public class UnitTest
	{
		[TestMethod]
		public void NullableBooleanUnitTest()
		{
			NullableBoolean nullable = new NullableBoolean();
			Assert.AreEqual(nullable.BooleanValue, false);

			nullable.BooleanValue = true;
			Assert.AreEqual<bool>(nullable.BooleanValue, true);

			nullable = new NullableBoolean(true);
			Assert.AreEqual<bool>(nullable.BooleanValue, true);

			nullable = new NullableBoolean("true");
			Assert.AreEqual<bool>(nullable.BooleanValue, true);
		}

		[TestMethod]
		public void NullableByteUnitTest()
		{
			NullableByte nullable = new NullableByte();
			Assert.AreEqual<byte>(nullable.ByteValue, byte.MinValue);

			nullable.ByteValue = byte.MaxValue;
			Assert.AreEqual<byte>(nullable.ByteValue, byte.MaxValue);

			nullable = new NullableByte(0x01);
			Assert.AreEqual<byte>(nullable.ByteValue, 0x01);

			nullable = new NullableByte(255);
			Assert.AreEqual<byte>(nullable.ByteValue, 255);

			nullable = new NullableByte("255");
			Assert.AreEqual<byte>(nullable.ByteValue, 0xFF);
		}

		[TestMethod]
		public void NullableCharUnitTest()
		{
			NullableChar nullable = new NullableChar();

			Assert.AreEqual<char>(nullable.CharValue, char.MinValue);

			nullable.CharValue = char.MaxValue;
			Assert.AreEqual<char>(nullable.CharValue, char.MaxValue);

			nullable = new NullableChar('?');
			Assert.AreEqual<char>(nullable.CharValue, '?');

			nullable = new NullableChar("?");
			Assert.AreEqual<char>(nullable.CharValue, '?');
		}

		[TestMethod]
		public void NullableDecimalUnitTest()
		{
			NullableDecimal nullable = new NullableDecimal();

			Assert.AreEqual<decimal>(nullable.DecimalValue, decimal.Zero);

			nullable.DecimalValue = decimal.MinusOne;
			Assert.AreEqual<decimal>(nullable.DecimalValue, decimal.MinusOne);

			nullable = new NullableDecimal(decimal.MinValue);
			Assert.AreEqual<decimal>(nullable.DecimalValue, decimal.MinValue);

			nullable = new NullableDecimal(decimal.MaxValue);
			Assert.AreEqual<decimal>(nullable.DecimalValue, decimal.MaxValue);

			nullable = new NullableDecimal("123.45");
			Assert.AreEqual<decimal>(nullable.DecimalValue, 123.45M);
		}

		[TestMethod]
		public void NullableDoubleUnitTest()
		{
			NullableDouble nullable = new NullableDouble();

			Assert.AreEqual<double>(nullable.DoubleValue, 0);

			nullable.DoubleValue = double.Epsilon;
			Assert.AreEqual<double>(nullable.DoubleValue, double.Epsilon);

			nullable = new NullableDouble(double.MinValue);
			Assert.AreEqual<double>(nullable.DoubleValue, double.MinValue);

			nullable = new NullableDouble(double.MaxValue);
			Assert.AreEqual<double>(nullable.DoubleValue, double.MaxValue);

			nullable = new NullableDouble("123.45");
			Assert.AreEqual<double>(nullable.DoubleValue, 123.45D);
		}

		[TestMethod]
		public void NullableFloatUnitTest()
		{
			NullableFloat nullable = new NullableFloat();

			Assert.AreEqual<float>(nullable.FloatValue, 0);

			nullable.FloatValue = float.Epsilon;
			Assert.AreEqual<float>(nullable.FloatValue, float.Epsilon);

			nullable = new NullableFloat(float.MinValue);
			Assert.AreEqual<float>(nullable.FloatValue, float.MinValue);

			nullable = new NullableFloat(float.MaxValue);
			Assert.AreEqual<float>(nullable.FloatValue, float.MaxValue);

			nullable = new NullableFloat("123.45");
			Assert.AreEqual<float>(nullable.FloatValue, 123.45F);
		}

		[TestMethod]
		public void NullableGuidUnitTest()
		{
			NullableGuid nullable = new NullableGuid();
			Guid guid = Guid.NewGuid();

			Assert.AreEqual<Guid>(nullable.GuidValue, Guid.Empty);

			nullable.GuidValue = guid;
			Assert.AreEqual<Guid>(nullable.GuidValue, guid);

			nullable = new NullableGuid(guid);
			Assert.AreEqual<Guid>(nullable.GuidValue, guid);

			nullable = new NullableGuid(guid.ToString());
			Assert.AreEqual<Guid>(nullable.GuidValue, guid);
		}

		[TestMethod]
		public void NullableIntUnitTest()
		{
			NullableInt nullable = new NullableInt();

			Assert.AreEqual<int>(nullable.IntValue, 0);

			nullable.IntValue = 123;
			Assert.AreEqual<int>(nullable.IntValue, 123);

			nullable = new NullableInt(int.MinValue);
			Assert.AreEqual<int>(nullable.IntValue, int.MinValue);

			nullable = new NullableInt(int.MaxValue);
			Assert.AreEqual<int>(nullable.IntValue, int.MaxValue);

			nullable = new NullableInt("789");
			Assert.AreEqual<int>(nullable.IntValue, 789);
		}

		[TestMethod]
		public void NullableLongUnitTest()
		{
			NullableLong nullable = new NullableLong();

			Assert.AreEqual<long>(nullable.LongValue, 0L);

			nullable.LongValue = 123L;
			Assert.AreEqual<long>(nullable.LongValue, 123L);

			nullable = new NullableLong(long.MinValue);
			Assert.AreEqual<long>(nullable.LongValue, long.MinValue);

			nullable = new NullableLong(long.MaxValue);
			Assert.AreEqual<long>(nullable.LongValue, long.MaxValue);

			nullable = new NullableLong("123");
			Assert.AreEqual<long>(nullable.LongValue, 123L);
		}

		[TestMethod]
		public void NullableSByteUnitTest()
		{
			NullableSByte nullable = new NullableSByte();

			Assert.AreEqual<sbyte>(nullable.SByteValue, 0);

			nullable.SByteValue = -123;
			Assert.AreEqual<sbyte>(nullable.SByteValue, -123);

			nullable = new NullableSByte(sbyte.MinValue);
			Assert.AreEqual<sbyte>(nullable.SByteValue, sbyte.MinValue);

			nullable = new NullableSByte(sbyte.MaxValue);
			Assert.AreEqual<sbyte>(nullable.SByteValue, sbyte.MaxValue);

			nullable = new NullableSByte("-123");
			Assert.AreEqual<sbyte>(nullable.SByteValue, -123);
		}

		[TestMethod]
		public void NullableShortUnitTest()
		{
			NullableShort nullable = new NullableShort();

			Assert.AreEqual<short>(nullable.ShortValue, 0);

			nullable.ShortValue = 123;
			Assert.AreEqual<short>(nullable.ShortValue, 123);

			nullable = new NullableShort(short.MinValue);
			Assert.AreEqual<short>(nullable.ShortValue, short.MinValue);

			nullable = new NullableShort(short.MaxValue);
			Assert.AreEqual<short>(nullable.ShortValue, short.MaxValue);

			nullable = new NullableShort("123");
			Assert.AreEqual<short>(nullable.ShortValue, 123);
		}

		[TestMethod]
		public void NullableUIntUnitTest()
		{
			NullableUInt nullable = new NullableUInt();

			Assert.AreEqual<uint>(nullable.UIntValue, 0);

			nullable.UIntValue = 123U;
			Assert.AreEqual<uint>(nullable.UIntValue, 123U);

			nullable = new NullableUInt(uint.MinValue);
			Assert.AreEqual<uint>(nullable.UIntValue, uint.MinValue);

			nullable = new NullableUInt(uint.MaxValue);
			Assert.AreEqual<uint>(nullable.UIntValue, uint.MaxValue);

			nullable = new NullableUInt("123");
			Assert.AreEqual<uint>(nullable.UIntValue, 123U);
		}

		[TestMethod]
		public void NullableULongUnitTest()
		{
			NullableULong nullable = new NullableULong();

			Assert.AreEqual<ulong>(nullable.ULongValue, 0);

			nullable.ULongValue = 123;
			Assert.AreEqual<ulong>(nullable.ULongValue, 123);

			nullable = new NullableULong(ulong.MinValue);
			Assert.AreEqual<ulong>(nullable.ULongValue, ulong.MinValue);

			nullable = new NullableULong(ulong.MaxValue);
			Assert.AreEqual<ulong>(nullable.ULongValue, ulong.MaxValue);

			nullable = new NullableULong("123");
			Assert.AreEqual<ulong>(nullable.ULongValue, 123);
		}

		[TestMethod]
		public void NullableUShortUnitTest()
		{
			NullableUShort nullable = new NullableUShort();

			Assert.AreEqual<ushort>(nullable.UShortValue, 0);

			nullable.UShortValue = 123;
			Assert.AreEqual<ushort>(nullable.UShortValue, 123);

			nullable = new NullableUShort(ushort.MinValue);
			Assert.AreEqual<ushort>(nullable.UShortValue, ushort.MinValue);

			nullable = new NullableUShort(ushort.MaxValue);
			Assert.AreEqual<ushort>(nullable.UShortValue, ushort.MaxValue);

			nullable = new NullableUShort("123");
			Assert.AreEqual<ushort>(nullable.UShortValue, 123);
		}
	}
}
